﻿package utils {
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.utils.Dictionary;
	import flash.utils.getTimer;

    public class Tween {

        private static const sprite:Sprite = new Sprite();

        private static var pool:Array = [];
        private static var list:Array = [];
        private static var threadMap:Dictionary = new Dictionary();

        public static function to(target:Object, time:int, propertie:Object, complete:Function=null, fun:Function=null):void{
            var thread:Thread;
            var key:String;
            if (threadMap[target]){
                thread = threadMap[target];
            } else {
                thread = ((pool.length > 0)) ? pool.pop() : new Thread();
                thread.target = target;
                list.push(thread);
                threadMap[target] = thread;
            };
            thread.beginTime = getTimer();
            thread.totleTime = time;
            thread.propertie = [];
            for (key in propertie) {
                thread.propertie.push([key, propertie[key][0], propertie[key][1]]);
            };
            thread.complete = complete;
            thread.fun = fun;
            start();
        }
        public static function stop(target:DisplayObject):void{
            var i:int = (list.length - 1);
            while (i >= 0) {
                if (list[i].target == target){
                    delete threadMap[list[i].target];
                    pool.push(list[i]);
                    list.splice(i, 1);
                };
                i--;
            };
        }
        private static function start():void{
            if (!(sprite.hasEventListener(Event.ENTER_FRAME))){
                sprite.addEventListener(Event.ENTER_FRAME, run);
            };
        }
        private static function run(e:Event):void{
            var thread:Thread;
            var j:int;
            var rate:Number;
            var value:Number;
            if (!(list.length)){
                sprite.removeEventListener(Event.ENTER_FRAME, run);
            };
            var now:int = getTimer();
            var i:int = (list.length - 1);
            while (i >= 0) {
                thread = list[i];
                j = 0;
                while (j < thread.propertie.length) {
                    rate = ((now - thread.beginTime) / thread.totleTime);
                    value = (thread.propertie[j][1] + (rate * (thread.propertie[j][2] - thread.propertie[j][1])));
                    thread.target[thread.propertie[j][0]] = ((thread.propertie[j][2] > thread.propertie[j][1])) ? ((value > thread.propertie[j][2])) ? thread.propertie[j][2] : value : ((value < thread.propertie[j][2])) ? thread.propertie[j][2] : value;
                    if (thread.fun != null){
                        thread.fun();
                    };
                    j++;
                };
                if ((now - thread.beginTime) > thread.totleTime){
                    list.splice(i, 1);
                    delete threadMap[thread.target];
                    pool.push(thread);
                    if (thread.complete != null){
                        thread.complete();
                    };
                };
                i--;
            };
        }
    }
}

import flash.display.*;

class Thread {

    public var target:Object;
    public var beginTime:int;
    public var totleTime:int;
    public var propertie:Array;
    public var complete:Function;
    public var fun:Function;

    public function Thread(){
    }
}
